Skip to main content

Webhooks

This document outlines the webhook functionality in the TrustChex system.

Overview

Webhooks allow your application to receive real-time notifications about events happening in your TrustChex account. When an event occurs, we'll send a HTTP POST request to the configured webhook URL.

Key Features:

  • Real-time event notifications
  • Automatic retry mechanism with exponential backoff
  • HMAC SHA256 signature verification for security
  • Comprehensive event logging and monitoring
  • Test functionality for easy debugging

Event Types

Verification Session Events

  • verification_session.created - A new verification session has been created
  • verification_session.completed - A verification session has been completed
  • verification_session.cancelled - A verification session has been cancelled

Identification Events

  • identification.created - A new identification has been created
  • identification.submitted - An identification has been submitted for review
  • identification.failed - An identification has failed processing
  • identification.in_automatic_review - An identification is under automatic review
  • identification.in_manual_review - An identification requires manual review
  • identification.waiting_for_status_change_approval - Status change requires approval
  • identification.approved - An identification has been approved
  • identification.rejected - An identification has been rejected
  • identification.resubmission_required - An identification requires resubmission

Managing Webhooks

Creating a Webhook

  1. Navigate to Settings > Webhooks in your dashboard
  2. Click "New Webhook"
  3. Configure your webhook:
    • URL: The endpoint where you want to receive webhook events
    • Description: Optional description for your webhook
    • Events: Select which event types you want to subscribe to
    • Active: Enable/disable the webhook
  4. Click "Save" to create your webhook

Testing Webhooks

Use the test button in the webhook dashboard to verify your endpoint:

  1. Click the Test button next to your webhook
  2. A test event will be sent to your endpoint
  3. Check the event logs to see the delivery status
  4. Review the request/response details for debugging

Webhook Payload

All webhooks include the following standard fields:

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"accountId": "your-account-id",
"webhookId": "webhook-id",
"eventType": "identification.approved",
"timestamp": "2024-01-01T12:00:00.000Z",
"data": {
"accountId": "your-account-id",
"identificationId": "identification-id",
"status": "APPROVED",
"email": "[email protected]",
"phoneNumber": "+1234567890",
"score": 95,
"createdAt": "2024-01-01T11:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
}

Event-Specific Payload Examples

Verification Session Data Structure

{
"data": {
"accountId": "your-account-id",
"sessionId": "session-id",
"status": "COMPLETED",
"identificationId": "identification-id",
"email": "[email protected]",
"phoneNumber": "+1234567890",
"locale": "en",
"sendOTP": true,
"createdAt": "2024-01-01T11:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z",
"expiresAt": "2024-01-01T13:00:00.000Z"
}
}

Identification Data Structure

{
"data": {
"accountId": "your-account-id",
"identificationId": "identification-id",
"status": "APPROVED",
"email": "[email protected]",
"phoneNumber": "+1234567890",
"score": 95,
"createdAt": "2024-01-01T11:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
}

Headers

Each webhook request includes these headers:

  • Content-Type: application/json
  • User-Agent: TrustChex-Webhook/1.0
  • X-Webhook-Event: {eventType}
  • X-Webhook-Delivery: {deliveryId}
  • X-Webhook-Timestamp: {timestamp}
  • X-Webhook-Secret: {secret} (if configured)
  • X-Webhook-Signature-256: sha256={signature} (if secret configured)

Security

Secret Verification

If you configure a secret for your webhook, we'll include it in the X-Webhook-Secret header and generate a HMAC SHA256 signature in the X-Webhook-Signature-256 header.

To verify the signature:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}

Delivery and Retries

  • Webhooks have a 30-second timeout
  • Failed deliveries are retried up to 3 times with exponential backoff (1s, 3s, 9s)
  • HTTP status codes 2xx are considered successful
  • All webhook attempts are logged and can be viewed in the dashboard

Testing

Use the test functionality in the webhook dashboard to send a test event to your endpoint:

{
"id": "test-delivery-id",
"accountId": "your-account-id",
"webhookId": "your-webhook-id",
"eventType": "test.webhook",
"timestamp": "2024-01-01T12:00:00.000Z",
"data": {
"message": "This is a test webhook delivery",
"test": true
}
}

Test Endpoint

For testing purposes, you can use our public webhook endpoint:

https://your-domain.com/api/public/webhooks

Query parameters:

  • ?fail=true - Simulate a failure (returns 500)
  • ?status=404 - Return specific status code
  • ?delay=5000 - Add delay in milliseconds (max 60000)

Best Practices

  1. Idempotency: Use the webhook delivery ID to avoid processing duplicate events
  2. Timeout Handling: Respond within 30 seconds to avoid timeouts
  3. Error Handling: Return appropriate HTTP status codes (2xx for success)
  4. Security: Always verify webhook signatures when using secrets
  5. Logging: Log webhook events for debugging and monitoring
  6. Graceful Degradation: Handle webhook failures gracefully in your application

Example Implementations

Node.js Express

const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json());

app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature-256'];
const secret = process.env.WEBHOOK_SECRET;

if (secret && signature) {
const payload = JSON.stringify(req.body);
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');

if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
return res.status(401).send('Unauthorized');
}
}

console.log('Webhook received:', req.body);

// Process the webhook event
switch (req.body.eventType) {
case 'identification.approved':
// Handle approval
break;
case 'identification.rejected':
// Handle rejection
break;
default:
console.log('Unknown event type:', req.body.eventType);
}

res.json({ received: true });
});

Python Flask

import hmac
import hashlib
import json
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Webhook-Signature-256')
secret = os.environ.get('WEBHOOK_SECRET')

if secret and signature:
payload = request.get_data()
expected_signature = 'sha256=' + hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()

if not hmac.compare_digest(signature, expected_signature):
return jsonify({'error': 'Unauthorized'}), 401

data = request.get_json()
print(f"Webhook received: {data}")

# Process the webhook event
event_type = data.get('eventType')
if event_type == 'identification.approved':
# Handle approval
pass
elif event_type == 'identification.rejected':
# Handle rejection
pass

return jsonify({'received': True})